package com.assistant.common.utils;

import com.alibaba.fastjson2.JSON;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 增强版HTTP工具类（支持GET/POST/文件上传/JSON）
 */
public class HttpClient {

    private static final int DEFAULT_TIMEOUT_MS = 100000;

    // ------------------- 公共配置 -------------------

    /**
     * 自定义请求配置
     */
    public static RequestConfig customConfig(int timeoutMs) {
        return RequestConfig.custom()
                .setConnectTimeout(timeoutMs)
                .setConnectionRequestTimeout(timeoutMs)
                .setSocketTimeout(timeoutMs)
                .build();
    }

    private static RequestConfig defaultConfig() {
        return customConfig(DEFAULT_TIMEOUT_MS);
    }
    // ------------------- POST请求（表单/JSON/文件） -------------------

    /**
     * POST表单请求
     */
    public static String doPostForm(String url, Map<String, String> formParams) throws IOException {
        return doPostForm(url, formParams, defaultConfig());
    }

    public static String doPostForm(String url, Map<String, String> formParams, RequestConfig config) throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = buildFormPost(url, formParams);
            httpPost.setConfig(config);
            return executeRequest(httpClient, httpPost);
        }
    }

    /**
     * POST JSON请求
     */
    public static String doPostJson(String url, Object jsonBody) throws IOException {
        return doPostJson(url, jsonBody, defaultConfig());
    }

    public static String doPostJson(String url, Object jsonBody, RequestConfig config) throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = buildJsonPost(url, jsonBody);
            httpPost.setConfig(config);
            return executeRequest(httpClient, httpPost);
        }
    }

    /**
     * POST文件上传（混合表单）
     */
    public static String doPostWithFiles(String url, Map<String, String> formParams,
                                         Map<String, File> fileParams) throws IOException {
        return doPostWithFiles(url, formParams, fileParams, defaultConfig());
    }

    public static String doPostWithFiles(String url, Map<String, String> formParams,
                                         Map<String, File> fileParams, RequestConfig config) throws IOException {
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = buildMultipartPost(url, formParams, fileParams);
            httpPost.setConfig(config);
            return executeRequest(httpClient, httpPost);
        }
    }

    // ------------------- 请求体构建 -------------------

    private static HttpPost buildFormPost(String url, Map<String, String> formParams) {
        HttpPost httpPost = new HttpPost(url);
        if (formParams != null) {
            List<NameValuePair> params = new ArrayList<>();
            formParams.forEach((k, v) -> params.add(new BasicNameValuePair(k, v)));
            httpPost.setEntity(new UrlEncodedFormEntity(params, StandardCharsets.UTF_8));
        }
        return httpPost;
    }

    private static HttpPost buildJsonPost(String url, Object jsonBody) {
        HttpPost httpPost = new HttpPost(url);
        if (jsonBody != null) {
            String jsonString = jsonBody instanceof String ? (String) jsonBody : JSON.toJSONString(jsonBody);
            StringEntity entity = new StringEntity(jsonString, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
        }
        return httpPost;
    }

    private static HttpPost buildMultipartPost(String url, Map<String, String> formParams,
                                               Map<String, File> fileParams) {
        HttpPost httpPost = new HttpPost(url);
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();

        // 添加文件
        if (fileParams != null) {
            fileParams.forEach((paramName, file) ->
                    builder.addPart(paramName, new FileBody(file, ContentType.DEFAULT_BINARY))
            );
        }

        // 添加表单字段
        if (formParams != null) {
            formParams.forEach((key, value) ->
                    builder.addTextBody(key, value, ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8))
            );
        }

        httpPost.setEntity(builder.build());
        return httpPost;
    }

    // ------------------- 核心执行逻辑 -------------------

    private static String executeRequest(CloseableHttpClient httpClient, HttpUriRequest request) throws IOException {
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode < 200 || statusCode >= 300) {
                throw new IOException("HTTP请求失败，状态码: " + statusCode);
            }
            HttpEntity entity = response.getEntity();
            return entity != null ? EntityUtils.toString(entity, StandardCharsets.UTF_8) : null;
        }
    }

    public static void downloadFile(String fileURL, String savePath) throws IOException {
        URL url = new URL(fileURL);
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("GET");
        httpConn.setRequestProperty("User-Agent", "Mozilla/5.0"); // 设置 User-Agent

        int responseCode = httpConn.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            // 确保保存目录存在
            Path path = Paths.get(savePath);
            Files.createDirectories(path.getParent());

            // 下载文件并保存到本地
            try (InputStream inputStream = httpConn.getInputStream();
                 FileOutputStream outputStream = new FileOutputStream(savePath)) {
                byte[] buffer = new byte[1024 * 16];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
            }
        }
    }
}